home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Personal Computer World 2009 February
/
PCWFEB09.iso
/
Software
/
Freeware
/
Griffith 0.9.8
/
griffith-0.9.8-win32.exe
/
{app}
/
lib
/
plugins
/
imp
/
CSV.py
< prev
Wrap
Text File
|
2008-11-17
|
13KB
|
415 lines
# -*- coding: UTF-8 -*-
__revision__ = '$Id: CSV.py 1040 2008-11-15 21:13:49Z mikej06 $'
###########################################################################
# Copyright (C) 2006-2007 by Jessica Katharina Parth
# <Jessica.K.P@women-at-work.org>
#
# Copyright: See COPYING file that comes with this distribution
#
###########################################################################
from plugins.imp import ImportPlugin as IP
import gtk
import gtk.glade
import os
import pygtk
import sys
import gutils
import string
def digits_only(s):
import string, re
_match = re.compile(r"\d+")
try:
s = reduce( string.join, _match.findall(s) )
except:
s = '0'
return s
def letters_only(s):
import string, re
_match = re.compile(r"\D+")
try:
s = reduce( string.join, _match.findall(s) )
except:
s = s
return s
class ImportPlugin(IP):
description = _("Full CSV list import plugin")
author = "Jessica Katharina Parth"
email = "Jessica.K.P@women-at-work.org"
version = "0.3"
file_filters = '*.[cC][sS][vV]'
mime_types = ('text/comma-separated-values', 'text/csv', 'application/csv')
def initialize(self):
if not IP.initialize(self):
return False
# glade
gf = os.path.join(self.locations['glade'], 'importcsv.glade')
# try to open the glade file
try:
self.gtk = gtk.glade.XML(gf)
except:
self.debug.show("Glade-file %s can not be loaded." % gf)
return False
# open gtk window
self.gtk.get_widget('d_import').set_transient_for( self.widgets['window'] )
# simple string lists
self.tv_csv = self.gtk.get_widget('tv_csv')
self.tv_assigned = self.gtk.get_widget('tv_assigned')
self.tv_griffith = self.gtk.get_widget('tv_griffith')
# 1st list
self.ls_csv = gtk.ListStore(str)
self.tv_csv.set_model(self.ls_csv)
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("none", renderer, text=0)
self.tv_csv.append_column(column)
# 2nd list
self.ls_griffith = gtk.ListStore(str,str)
self.tv_griffith.set_model(self.ls_griffith)
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("none", renderer, text=0)
column.set_visible(False)
self.tv_griffith.append_column(column)
column = gtk.TreeViewColumn("none", renderer, text=1)
self.tv_griffith.append_column(column)
self.set_griffith_fields()
# 3rd list
self.ls_assigned = gtk.ListStore(str,str,str)
self.tv_assigned.set_model(self.ls_assigned)
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn("none", renderer, text=0)
self.tv_assigned.append_column(column)
# add the columns for internal information handling and hide them
column = gtk.TreeViewColumn("none", renderer, text=1)
column.set_visible(False)
self.tv_assigned.append_column(column)
column = gtk.TreeViewColumn("none", renderer, text=2)
column.set_visible(False)
self.tv_assigned.append_column(column)
# hide tabs
self.nb_pages = self.gtk.get_widget('nb_pages')
self.nb_pages.get_nth_page(1).hide()
self.nb_pages.connect("switch-page", self._on_page_changed)
# Events
# Buttons
self.b_cancel = self.gtk.get_widget("b_cancel")
self.b_cancel.connect("clicked", self._clicked)
self.b_next = self.gtk.get_widget("b_next")
self.b_next.connect("clicked", self._clicked)
self.b_back = self.gtk.get_widget("b_back")
self.b_back.connect("clicked", self._clicked)
self.b_add = self.gtk.get_widget("b_add")
self.b_add.connect("clicked", self._clicked)
self.b_del = self.gtk.get_widget("b_del")
self.b_del.connect("clicked", self._clicked)
# Treeviews
self.tv_griffith.connect("row_activated", self._on_row_activated)
self.tv_griffith.connect("cursor_changed", self._on_cursor_changed)
self.tv_csv.connect("row_activated", self._on_row_activated)
self.tv_csv.connect("cursor_changed", self._on_cursor_changed)
self.tv_assigned.connect("cursor_changed", self._on_cursor_changed)
self.gtk.get_widget('e_lineterminator').set_active(0)
self.selected_griffith = None
self.selected_csv = None
self.current_csv_row = 0
self.csv_header = None
return True
def set_griffith_fields(self):
# 2nd list
sorted_list = ( "number", "title", "o_title", "director", "year", "country",
"cast", "studio", "plot", "runtime", "genre", "classification",
"site", "o_site", "trailer", "image", "seen", "loaned", "notes",
"rating", "movie_id", "collection_id", "volume_id", "medium_id",
"vcodec_id", "color", "cond", "layers", "region", "media_num" )
# sort the list and add field and translated field-name
for sorted in sorted_list:
for name in self.fields_to_import:
if sorted == name:
iterator = self.ls_griffith.append()
self.ls_griffith.set_value(iterator, 0, name)
self.ls_griffith.set_value(iterator, 1, self.fields[name])
def create_import_table(self):
self.import_table = {}
item = self.ls_assigned.get_iter_first()
while item is not None:
self.import_table[self.ls_assigned.get_value(item,1)] = self.ls_assigned.get_value(item,2)
item = self.ls_assigned.iter_next(item)
def _on_page_changed(self, notebook, page, page_num):
if page_num == 0:
self.b_back.set_sensitive(False)
if page_num == 1:
self.b_back.set_sensitive(True)
self.open_source()
def _clicked(self, widget, event=None, data=None):
if widget == self.b_cancel:
self.gtk.get_widget('d_import').hide()
self.gtk.get_widget('d_import').response(gtk.RESPONSE_CANCEL)
if widget == self.b_back:
if self.nb_pages.get_current_page() == 1:
self.nb_pages.prev_page()
if widget == self.b_next:
if self.nb_pages.get_current_page() == 0:
self.nb_pages.get_nth_page(1).show()
self.nb_pages.next_page()
else:
if self.nb_pages.get_current_page() == 1:
# test if at least one field is assigned
if self.ls_assigned.get_iter_first() is not None:
# prepare tabelle for import
self.create_import_table()
# hide everything
self.gtk.get_widget('d_import').hide()
self.gtk.get_widget('d_import').response(gtk.RESPONSE_OK)
else:
gutils.info(self.gtk, _("Please assign at least one field first!"), self.gtk.get_widget('d_import') )
if widget == self.b_add:
iterator = self.ls_assigned.append()
self.ls_assigned.set_value(iterator, 0, "%s > %s" % (self.selected_csv, self.fields[self.selected_griffith]) )
# add information for the import tabelle
self.ls_assigned.set_value(iterator, 1, self.selected_griffith )
self.ls_assigned.set_value(iterator, 2, str(self.csv_header.index(self.selected_csv)) )
self.ls_griffith.remove(self.iter_griffith)
self.selected_griffith = None
self.b_add.set_sensitive(False)
if widget == self.b_del:
# re-add field to griffith
field_name = self.ls_assigned.get_value(self.iter_assigned,1)
iterator = self.ls_griffith.append()
self.ls_griffith.set_value(iterator, 0, field_name)
self.ls_griffith.set_value(iterator, 1, self.fields[field_name])
# remove assigned row
self.ls_assigned.remove(self.iter_assigned)
self.b_del.set_sensitive(False)
def _on_row_activated(self, treeview, path, view_column, data = None):
# get selected rows from both treeviews/lists
if treeview == self.tv_griffith:
self.iter_griffith = self.ls_griffith.get_iter(path)
if self.iter_griffith:
self.selected_griffith = self.ls_griffith.get_value(self.iter_griffith,0)
if treeview == self.tv_csv:
iter = self.ls_csv.get_iter(path)
if iter:
self.selected_csv = self.ls_csv.get_value(iter,0)
# enable add button if both lists have a selected item
if self.selected_griffith is not None and self.selected_csv is not None:
self.b_add.set_sensitive(True)
else:
self.b_add.set_sensitive(False)
def _on_cursor_changed(self, widget, data1 = None, data2 = None):
# get selected rows from both treeviews/lists
selection = widget.get_selection()
(model,iter) = selection.get_selected()
if widget == self.tv_griffith:
self.iter_griffith = iter
if self.iter_griffith:
self.selected_griffith = str(model.get_value(self.iter_griffith, 0))
else:
self.selected_griffith = None
if widget == self.tv_csv:
if iter:
self.selected_csv = str(model.get_value(iter, 0))
else:
self.selected_csv = None
if widget == self.tv_assigned:
self.iter_assigned = iter
if self.iter_assigned:
self.b_del.set_sensitive(True)
else:
self.b_del.set_sensitive(False)
# enable add button if both lists have a selected item
if self.selected_griffith is not None and self.selected_csv is not None:
self.b_add.set_sensitive(True)
else:
self.b_add.set_sensitive(False)
def open_source(self):
import csv, codecs, os
# get user values for converting/opening the csv-file
self.start_row = int(digits_only( self.gtk.get_widget('e_startrow').get_text() ))
encoding = self.gtk.get_widget('e_encoding').get_active_text()
encoding = encoding[:string.find( encoding, ' ' )]
delimiter = self.gtk.get_widget('e_delimiter').get_text()
if delimiter == '':
delimiter = ","
# quotechar
quotechar = self.gtk.get_widget('e_quotechar').get_text()
if quotechar == '':
quotechar == '"'
# lineterminator
active = self.gtk.get_widget('e_lineterminator').get_active()
# default for none selected and the same for linux and macintosh
lineterminator = '\r'
# windows lineterminator
if active == 1:
lineterminator = '\r\n'
# open file
try:
self.data = csv.reader(codecs.open(self.__source_name, 'r', encoding), dialect='excel', quotechar=quotechar, delimiter=delimiter, lineterminator = lineterminator)
# get the first line in csv file for the field names
self.csv_header = self.data.next()
# if the user wants to import line 0 then we have to open it again
if self.start_row == 0:
self.data = csv.reader(codecs.open(self.__source_name, 'r', encoding), dialect='excel', quotechar=quotechar, delimiter=delimiter, lineterminator = lineterminator)
# fill the found csv-headers in the simple string list
self.ls_csv.clear()
for name in self.csv_header:
iterator = self.ls_csv.append()
self.ls_csv.set_value(iterator, 0, name)
return True
except:
gutils.info(self.gtk, _("Can't open the file %s") % self.__source_name, self.gtk.get_widget('d_import') )
return False
def set_source(self, name):
import os
# source _dependent_ initialization goes here
if name is None or not os.path.isfile(name):
return False
self.__source_name = name
# auto-detect file-encoding (optional)
try:
from chardet.universaldetector import UniversalDetector
detector = UniversalDetector()
detector.reset()
lines = 0
for line in file(self.__source_name, 'rb'):
detector.feed(line)
lines += 1
if detector.done or lines == 50:
break
detector.close()
encoding = string.replace( string.lower( detector.result['encoding'] ), '-', '' )
except:
encoding = 'utf_8'
# remove - and _ for better detection
encoding = string.replace( encoding, '_', '' )
model = self.gtk.get_widget('e_encoding').get_model()
itempos = 0
for item in model:
pos1 = string.find( string.replace( string.lower(str(item[0])), '_', '' ) , encoding )
if pos1 == 0:
break
itempos += 1
self.gtk.get_widget('e_encoding').set_active(itempos)
# run dialog
response = self.gtk.get_widget('d_import').run()
if response == gtk.RESPONSE_OK:
return True
else:
return False
def count_movies(self):
i = 0
try:
import csv
data = csv.reader(open(self.__source_name))
while data.next():
i += 1
except:
return i
def get_movie_details(self):
try:
item = self.data.next()
except:
return None
if item is None:
return None
import copy
# start with the right line
self.current_csv_row += 1
if (self.current_csv_row ) < self.start_row:
return None
# assign the keys
t_movies = copy.deepcopy(self.import_table)
# values are overwritten here with the imports
for field in self.import_table:
try:
# some minor fixes to the import so it fits the griffith variable types
if field == 'year' or field == 'runtime' or field == 'media_num' or field == 'number' or field == 'volume_id':
t_movies[field] = int( digits_only( item[ int(self.import_table[field]) ] ) )
elif field == 'seen' or field == 'loaned':
t_movies[field] = bool( item[ int(self.import_table[field]) ] )
elif field == 'country':
t_movies[field] = letters_only( item[ int(self.import_table[field]) ] )
elif field == 'cast':
try:
if item[ int(self.import_table[field]) ].index(", ") != -1:
t_movies[field] = string.replace( item[ int(self.import_table[field]) ], ", ", "\n" )
except:
t_movies[field] = string.replace( item[ int(self.import_table[field]) ], ",", "\n" )
else:
# 1:1 import
t_movies[field] = item[ int(self.import_table[field]) ]
except:
# error field can't be imported
t_movies.pop(field)
return t_movies
def clear(self):
IP.clear(self)
self.nb_pages.get_nth_page(1).hide()
self.csv_header = None
self.ls_assigned.clear()
self.ls_griffith.clear()
# add default griffith fields again
self.set_griffith_fields()
def destroy(self):
self.gtk.get_widget('d_import').destroy()